package com.beta.config.security;

import com.beta.config.security.base.Role;
import com.nimbusds.jose.shaded.json.JSONArray;
import com.nimbusds.jose.shaded.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;

import java.util.ArrayList;
import java.util.Collection;

@Configuration
@EnableWebSecurity
public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {
    @Value("${spring.security.role.admin}")
    private String role_admin;

    protected void configure(HttpSecurity http) throws Exception{
        JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
        converter.setJwtGrantedAuthoritiesConverter(new Converter<Jwt, Collection<GrantedAuthority>>() {
            @Override
            public Collection<GrantedAuthority> convert(Jwt source) {
                JSONArray roles = (JSONArray) ((JSONObject) (source.getClaims().get("realm_access"))).get("roles");
//                JSONArray scopes = (JSONArray) ((JSONObject) (source.getClaims().get("resource_access"))).get("roles");
                ArrayList<GrantedAuthority> roleArray = new ArrayList<>();
                for(int i = 0; i < roles.size(); i++){
                    roleArray.add(new Role(roles.get(i)));
                }
                return roleArray;
            }
        });
        http.authorizeRequests(authz -> authz
                        .antMatchers(HttpMethod.POST, "/encrypt").hasRole(role_admin)
                        .antMatchers(HttpMethod.POST, "/decrypt").hasRole(role_admin)
                        .anyRequest().permitAll())
                .oauth2ResourceServer().jwt().jwtAuthenticationConverter(converter);
    }
}
